package com.userqiao.linework.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.userqiao.linework.dao.TbUserDao;
import com.userqiao.linework.entity.TbUser;
import com.userqiao.linework.exception.LineWorkException;
import com.userqiao.linework.service.TbUserService;
import com.userqiao.linework.task.EmailTask;
import com.userqiao.linework.wx.WxServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 用户表(TbUser)表服务实现类
 *
 * @author makejava
 * @since 2021-02-17 00:22:02
 */
@Service("tbUserService")
public class TbUserServiceImpl implements TbUserService {
    @Resource
    private TbUserDao tbUserDao;
    @Resource
    private WxServer wxServer;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private EmailTask emailTask;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public TbUser queryById(Integer id) {
        return this.tbUserDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<TbUser> queryAllByLimit(int offset, int limit) {
        return this.tbUserDao.queryAllByLimit(offset, limit);
    }


    /**
     * 修改数据
     *
     * @param tbUser 实例对象
     * @return 实例对象
     */
    @Override
    public TbUser update(TbUser tbUser) {
        this.tbUserDao.update(tbUser);
        return this.queryById(tbUser.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.tbUserDao.deleteById(id) > 0;
    }

    @Override
    public String getOpenId(String code) {
        String openId = wxServer.getOpenIdByUser(code);
        if (openId == null || openId.length() == 0){
            throw new RuntimeException("临时登录凭证错误");
        }
        return openId;
    }

    @Override
    public int registerUser(String registerCode, String code, String nickname, String photo) {
        //如果邀请码是000000，代表是超级管理员
        if (registerCode.equals("000000")){
            //查询超级管理员帐户是否已经绑定
            boolean bool = tbUserDao.haveAdminUser();
            if (!bool) {
                //把当前用户绑定到ROOT帐户
                String openId = getOpenId(code);
                Map param = new HashMap();
                param.put("openId", openId);
                param.put("nickname", nickname);
                param.put("photo", photo);
                param.put("role", "[0]");
                param.put("status", 1);
                param.put("createTime", new Date());
                param.put("root", true);
                tbUserDao.insert(param);
                int id = tbUserDao.searchIdByOpenId(openId);
                return id;
            } else {
                //如果root已经绑定了，就抛出异常
                throw new LineWorkException("无法绑定超级管理员账号");
            }
        }else{
            // 非超级管理员登录
            if (!redisTemplate.hasKey(registerCode)){
                throw new LineWorkException("邀请码无效，请联系管理员");
            }
            String userId = redisTemplate.opsForValue().get(registerCode).toString();
            TbUser tbUser = tbUserDao.queryById(Integer.parseInt(userId));
            if (tbUser == null){
                throw new LineWorkException("找不到用户，请联系管理员");
            }
            String openId = getOpenId(code);
            tbUser.setOpenId(openId);
            tbUser.setNickname(nickname);
            tbUser.setPhoto(photo);
            tbUser.setRoot(false);
            tbUserDao.update(tbUser);
            // 员工注册成功后清楚Redis的缓存数据
            redisTemplate.delete(registerCode);
        }
        return 0;
    }

    @Override
    public Set<String> searchUserPermissions(int userId) {
        Set<String> permissions=tbUserDao.searchUserPermissions(userId);
        return permissions;
    }

    @Override
    public Integer login(String code) {
        String openId = getOpenId(code);
        Integer id = tbUserDao.searchIdByOpenId(openId);
        if (id == null) {
            throw new LineWorkException("帐户不存在");
        }
        //TODO 从消息队列中接收消息，转移到消息表
        return id;
    }

    @Override
    public boolean saveUser(TbUser tbUser) {
        //1、检查下有没有员工的用户名、邮箱两个关键信息

        //2、将用户保存到数据库当中去
        // 入职时间为管理员添加用户的时间
        tbUser.setHiredate(new Date());
        tbUser.setDeptId(3);
        int i = tbUserDao.insertEntity(tbUser);
        if (i<=0){
            throw new LineWorkException("添加用户失败");
        }
        //3、生成六位随机码，并且保存到Redis当中去。
        Integer[] integers = NumberUtil.generateBySet(100000, 999999, 1);
        Integer code = integers[0];
        redisTemplate.opsForValue().set(code.toString(),tbUser.getId());
        //4、发送邮件给指定邮箱
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(tbUser.getEmail());
        message.setSubject("加入Line-Work的邀请函");
        message.setText(tbUser.getName()+"您好，欢迎您加入我们的大家庭，您的Line-Work系统的邀请码为:"+code+"。请尽快注册进入系统");
        emailTask.sendAsync(message);
        //5、返回执行结果
        return true;
    }

    @Override
    public String searchUserHiredate(int userId) {
        String hiredate = tbUserDao.getUserHiredate(userId);
        return hiredate;
    }

    @Override
    public Map searchUserSummary(int userId) {
        return tbUserDao.searchUserSummary(userId);
    }
}